package com.ys.service.finance.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.dto.AddDto;
import com.ys.entity.business.TbBaseInfo;
import com.ys.entity.finance.TcwCapitalRegister;
import com.ys.entity.finance.TcwCapitalRegisterClaim;
import com.ys.entity.finance.TcwCapitalRegisterSon;
import com.ys.entity.flow.YspModel;
import com.ys.entity.hr.ThrOperateCompanyBankInfo;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsCol;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.base.TransactionTypeEnum;
import com.ys.enume.finance.TcwFinancialTransactionFlowEnum;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.mapper.finance.FinanceMapper;
import com.ys.mapper.finance.TcwCapitalRegisterClaimMapper;
import com.ys.mapper.finance.TcwCapitalRegisterMapper;
import com.ys.mapper.finance.TcwCapitalRegisterSonMapper;
import com.ys.service.business.TcwAccountDetailedForCompanyService;
import com.ys.service.finance.TcwCapitalRegisterService;
import com.ys.service.finance.TcwFinancialTransactionFlowService;
import com.ys.service.flow.YspTaskService;
import com.ys.util.CheckUtil;
import com.ys.util.DateUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;

/**
 * 资金登记单
 */
@Service("tcwCapitalRegister")
public class TcwCapitalRegisterServiceImpl implements TcwCapitalRegisterService {
	private static final Logger logger = LoggerFactory.getLogger(TcwCapitalRegisterServiceImpl.class);

	@Autowired
	private TcwCapitalRegisterMapper tcwCapitalRegisterMapper;

	@Autowired
	private TcwCapitalRegisterSonMapper tcwCapitalRegisterSonMapper;

	@Autowired
	private TcwCapitalRegisterClaimMapper tcwCapitalRegisterClaimMapper;

	@Autowired
	private TcwAccountDetailedForCompanyService tcwAccountDetailedForCompanyService;

	@Autowired
	private YspTaskService yspTaskService;

	@Autowired
	private CheckUtil checkUtil;

	@Autowired
	private FinanceMapper financeMapper;

	@Autowired
	private TcwFinancialTransactionFlowService tcwFinancialTransactionFlowService;

	/**
	 * 新增
	 */
	@Override
	public R add(Map<String, Object> params, Long menuId) throws Exception{
		logger.info("新增传参:"+params);
		//参数验证
		String errorBack = checkParams(params, menuId);
		if(errorBack!=null && !"".equals(errorBack)){
			return R.error(errorBack);
		}
		TcwCapitalRegister tcwCapitalRegister = JSON.parseObject(JSON.toJSONString(params), TcwCapitalRegister.class);
		tcwCapitalRegister.setStatus(1);//状态
		tcwCapitalRegister.setEffectStock(0);//审批状态
		tcwCapitalRegister.setVgsbm("GS0874");//收款运营公司编码

		//获取制单人信息
		TsUserChange tsUserChange = new TsUserChange().setUserId(ShiroUtils.getUserId()).setOrderby("A.CreateTime DESC").queryFirst();
		if(tsUserChange!=null){
			tcwCapitalRegister.setCreateChangeId(tsUserChange.getId());//制单人变更信息
		}else {
			return R.error("未查询到制单人信息！");
		}

		//保存列表信息
		R saveItemRes = saveItem(params,tcwCapitalRegister);
		if(saveItemRes.getCode()==1){
			return saveItemRes;
		}

		//新增
		tcwCapitalRegisterMapper.insert(tcwCapitalRegister);

		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, tcwCapitalRegister.getBid(), createUserId);
		}
		//return R.ok(EditDto.closeAndReload());
		return R.ok(AddDto.gotoEdit("/web/finance/tcwCapitalRegister/toEdit?bid=" + tcwCapitalRegister.getBid()));
	}


	/**
	 * 修改
	 */
	@Override
	public R update(Map<String, Object> params, Long menuId) throws Exception{
		logger.info("修改传参:"+params);
		//参数验证
		String errorBack = checkParams(params, menuId);
		if(errorBack!=null && !"".equals(errorBack)){
			return R.error(errorBack);
		}
		TcwCapitalRegister tcwCapitalRegister = JSON.parseObject(JSON.toJSONString(params), TcwCapitalRegister.class);
		// 验证状态
		YsProcInst ysProcInst = new YsProcInst().setBid(tcwCapitalRegister.getBid()).queryFirst();
		if (ysProcInst == null) {
			return R.error("审批数据不存在，无法编辑");
		} else if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.INIT.value) {
			return R.error("已流转，无法编辑");
		}

		//保存列表信息
		R saveItemRes = saveItem(params,tcwCapitalRegister);
		if(saveItemRes.getCode()==1){
			return saveItemRes;
		}
		tcwCapitalRegisterMapper.update(tcwCapitalRegister);
		return R.ok();
	}


	//保存列表信息
	public R saveItem(Map<String, Object> params,TcwCapitalRegister tcwCapitalRegister){
		//保存列表信息
		List<Map<String, Object>> paramsNewByItem = new ArrayList<>();
		if(params.get("subData")!=null){
			//验证详情信息
			JSONArray subData = JSON.parseArray(params.get("subData").toString());
			String errorBackByItem = null;//错误信息
			if(subData!=null && subData.size()>0){
				for (int i = 0; i < subData.size(); i++) {
					JSONObject jSONObject = subData.getJSONObject(i);
					Map<String, Object> paramsNewByRecord = new HashMap<>();
					if(jSONObject.get("id")!=null && !"".equals(jSONObject.get("id")))paramsNewByRecord.put("id",jSONObject.get("id"));//id
					if(jSONObject.get("remark")!=null && !"".equals(jSONObject.get("remark")))paramsNewByRecord.put("remark",jSONObject.get("remark"));
					if(jSONObject.get("paymentTime")!=null && !"".equals(jSONObject.get("paymentTime"))){
						paramsNewByRecord.put("paymentTime",jSONObject.get("paymentTime"));//收款时间
					}else {
						errorBackByItem = "第"+(i+1)+"行的收款时间信息为空！";
					}
					if(jSONObject.get("operateCompanyBankInfoId")!=null && !"".equals(jSONObject.get("operateCompanyBankInfoId"))){
						paramsNewByRecord.put("operateCompanyBankInfoId",jSONObject.get("operateCompanyBankInfoId"));//运营公司银行账户
					}else {
						errorBackByItem = "第"+(i+1)+"行的运营公司银行账户信息为空！";
					}
					if(jSONObject.get("paymentAmount")!=null && !"".equals(jSONObject.get("paymentAmount"))){
						if(!checkUtil.isDecimal(jSONObject.get("paymentAmount").toString(),"2")){
							errorBackByItem = "第"+(i+1)+"行的付款金额应为2位小数！";
						}
						paramsNewByRecord.put("paymentAmount",jSONObject.get("paymentAmount"));//付款金额
					}else {
						errorBackByItem = "第"+(i+1)+"行的付款金额为空！";
					}
					if(checkUtil.isNullByObject(jSONObject.get("claimVgsmc"))){
						errorBackByItem = "第"+(i+1)+"行，需要填写登记认领公司全称！";
					}else {
						paramsNewByRecord.put("claimVgsmc",jSONObject.get("claimVgsmc"));//id
					}
					//当为个人户时，需要填写认领公司全称
					if(checkUtil.isNotNullByObject(jSONObject.get("accountType")) && jSONObject.get("accountType").toString().equals("1")){
						if(checkUtil.isNullByObject(jSONObject.get("claimVgsmc"))){
							errorBackByItem = "第"+(i+1)+"行，当为个人户时，需要填写登记认领公司全称！";
						}
						if(checkUtil.isNotNullByObject(jSONObject.get("claimVgsmc")))paramsNewByRecord.put("claimVgsmc",jSONObject.get("claimVgsmc").toString().trim());
					}
					/*
					//当为对公户时
					if(checkUtil.isNotNullByObject(jSONObject.get("accountType")) && jSONObject.get("accountType").toString().equals("0")){
						if(checkUtil.isNotNullByObject(jSONObject.get("vyhzhmc")))paramsNewByRecord.put("claimVgsmc",jSONObject.get("vyhzhmc").toString().trim());
					}

					 */


					paramsNewByItem.add(paramsNewByRecord);
				}
				if(errorBackByItem!=null && !"".equals(errorBackByItem)){
					return R.error(errorBackByItem);
				}
			}else {
				return R.error("列表信息为空！");
			}
		}else {
			return R.error("列表信息为空！");
		}

		//删除列表信息
		financeMapper.deleteTcwCapitalRegisterSonByPbid(tcwCapitalRegister.getBid());

		for (int i = 0; i < paramsNewByItem.size(); i++) {
			Map<String, Object> item = paramsNewByItem.get(i);
			TcwCapitalRegisterSon tcwCapitalRegisterSon = JSON.parseObject(JSON.toJSONString(item), TcwCapitalRegisterSon.class);
			tcwCapitalRegisterSon.setStatus(1);
			tcwCapitalRegisterSon.setPbid(tcwCapitalRegister.getBid());
			//新增
			tcwCapitalRegisterSonMapper.insert(tcwCapitalRegisterSon);
			/*
			if(tcwCapitalRegisterSon.getId()!=null){
				//修改
				tcwCapitalRegisterSonMapper.update(tcwCapitalRegisterSon);
			}else {
				//新增
				tcwCapitalRegisterSonMapper.insert(tcwCapitalRegisterSon);
			}
			 */
		}
		return R.ok();
	}


	//删除
	@Override
	@Transactional
	public R del(Long id) throws Exception{
		if (id == null) {
			return R.error("ID不能为空");
		}
		TcwCapitalRegister entity = new TcwCapitalRegister().setId(id).queryFirst();
		if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
			return R.error("已生效数据无法删除");
		}
		// 验证是否制单人
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();
		if (!tsUserChange.getUserId().equals(loginUserId) && !"admin".equals(loginUserId)) {
			return R.error("非制单人，无法删除");
		}
		//删除
		tcwCapitalRegisterMapper.deleteTrue(id);
		//删除列表信息
		financeMapper.deleteTcwCapitalRegisterSonByPbid(entity.getBid());
		//删除流程
		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}

	//删除列表
	@Override
	@Transactional
	public R toDelByItem(Long id) throws Exception{
		logger.info("删除传参:"+id);
		tcwCapitalRegisterSonMapper.deleteTrue(id);
		return R.ok();
	}



	/**
	 * 流转通过
	 */
	@Override
	@Transactional
	public R flowPass(Long id, String loginUserId) throws Exception {

		TcwCapitalRegister entity = new TcwCapitalRegister().setId(id).queryFirst();
		Flow f = yspTaskService.flowPass(entity.getBid(), loginUserId);
		if (f.getCode() == Flow.Code.FAILED.value) {
			return R.error(f.getMsg());
		} else {
			if (f.getState() == Flow.State.FINISH.value) {
				return flowFinish(entity.getBid());
			}
			return R.ok();
		}
	}

	/**
	 * 流转结束
	 */
	@Override
	@Transactional
	public R flowFinish(String bid) throws Exception {

		TcwCapitalRegister entity = new TcwCapitalRegister().setBid(bid).queryFirst();
		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
		if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
			return R.error("流程未流转到最后一步！");
		}
		Date theDate = new Date();
		entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
		entity.setUpdateTime(theDate);

		//信息新增至“资金登记认领表”
		//获取详情信息
		List<TcwCapitalRegisterSon> tcwCapitalRegisterSonList = new TcwCapitalRegisterSon().setPbid(bid).queryList();

		String transactionTypeStr = TransactionTypeEnum.FinanceType.TCW_CapitalRegister.name;
		TbBaseInfo transactionTypeItem = tcwFinancialTransactionFlowService.getTransactionType(transactionTypeStr);

		for (TcwCapitalRegisterSon sonItem : tcwCapitalRegisterSonList){
			//新增资金登记认领表
			TcwCapitalRegisterClaim tcwCapitalRegisterClaim = new TcwCapitalRegisterClaim();
			tcwCapitalRegisterClaim.setCapitalRegisterSonId(sonItem.getId());
			tcwCapitalRegisterClaim.setPaymentTime( DateUtil.getYYYY_MM_DD(sonItem.getPaymentTime()));//收款时间
			tcwCapitalRegisterClaim.setPaymentAmount(sonItem.getPaymentAmount());//付款金额
			tcwCapitalRegisterClaim.setAccountingVgsbm(entity.getVgsbm());//收款运营公司编码
			tcwCapitalRegisterClaim.setCompanyVid(entity.getCompanyVid());//收款公司编码
			tcwCapitalRegisterClaim.setOperateCompanyBankInfoId(sonItem.getOperateCompanyBankInfoId());//运营公司银行账户Id(付款信息)
			tcwCapitalRegisterClaim.setCompanyBankInfoId(entity.getCompanyBankInfoId());

			tcwCapitalRegisterClaim.setClaimStatus(0);//认领状态（0未认领、1已认领）
			tcwCapitalRegisterClaim.setStatus(1);
			tcwCapitalRegisterClaim.setCapitalRegisterSonId(sonItem.getId());
			tcwCapitalRegisterClaimMapper.insert(tcwCapitalRegisterClaim);

			ThrOperateCompanyBankInfo thrOperateCompanyBankInfo = new ThrOperateCompanyBankInfo().setId(sonItem.getOperateCompanyBankInfoId()).queryFirst();
			if(thrOperateCompanyBankInfo!=null){
				/**
				 * 新增一条流水
				 * 必填：vgsbm划出公司编码；vgsbmp划入公司编码；vjylx交易类型；fje交易金额；djysj交易时间；dshsj审核时间；vbz备注
				 * 选填：mname;mtype;mnid;mbid;mguid；writeTime记账时间（如果为空，默认审核时间）
				 */
				tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJc(
						"GS0874","挂账账户",thrOperateCompanyBankInfo.getVid(),thrOperateCompanyBankInfo.getVyhzhmc(),
						transactionTypeStr, sonItem.getPaymentAmount(),entity.getCreateTime(), theDate,"资金登记单："+entity.getBid(),entity.getBid(),
						sonItem.getPaymentTime());

				if(transactionTypeItem!=null && transactionTypeItem.getId()!=null){
					//财务交易流水
					R res = tcwFinancialTransactionFlowService.add(true, entity.getCompanyBankInfoId(), transactionTypeItem.getBid(),
							thrOperateCompanyBankInfo.getVyhzhmc(), thrOperateCompanyBankInfo.getVkhh(), thrOperateCompanyBankInfo.getVyhzh(),
							sonItem.getPaymentAmount(),entity.getCreateTime(),theDate, new Date(), "资金登记单："+entity.getBid()+"，备注："+(sonItem.getRemark()!=null?sonItem.getRemark():""),
							TcwFinancialTransactionFlowEnum.FromType.TCW_CapitalRegisterSon.value, sonItem.getId());
					if(res.getCode().equals( R.Code.FAILED.value)){
						throw new IllegalArgumentException(res.getMsg());
					}
				}


			}
		}

		//修改信息
		tcwCapitalRegisterMapper.update(entity);

		return R.ok();
	}



	/**
	 * 参数验证
	 */
	public String checkParams(Map<String, Object> params, Long menuId) throws Exception {
		//获取pc字段数据
		List<YsCol> listField = new YsCol()
				.where("A.MenuId = "+menuId)
				.setOrderby("A.SortNo ASC")
				.queryList();
		//验证必填字段的非空；其他字段的长度限制、类型
		String backMsg = checkUtil.checkTableColLengthAndDataType("TCW_CapitalRegister",listField,params,ysColItem->ysColItem.getFormEditRequired()!=null && ysColItem.getFormEditRequired() == 1);
		return backMsg;
	}



	//获取列表数据
	@Override
	@Transactional
	public Map<String,Object> getExtraParam( String bid) throws Exception{
		Map<String,Object> extraParam = new TcwCapitalRegister()

				.addLeftJoin("TS_UserChange U ON U.Id = A.CreateChangeId ")
				.addField("U.UserId + '/' + U.UserName AS _ys_createUserName")//制单人

				.addLeftJoin("YS_ProcInst P ON P.Bid = A.Bid ")
				.addField("P.Bid AS instBid")
				.addField("FORMAT(P.UpdateTime, 'yyyy-MM-dd HH:mm:ss') AS auditingTime")//审核时间

				.addLeftJoin("THR_OperateCompanyApply OCA ON OCA.Vgsbm = A.Vgsbm")
				.addField("OCA.Vgsjc AS vgsjc")//收款运营公司简称
				.addField("OCA.Vgsmc AS vgsmc")//收款运营公司名称

				//.addField("'运营服务→预付款' AS vjylx")//交易类型

				.addLeftJoin("TB_CompanyInfo C ON C.Vid = A.CompanyVid ")
				.addField("C.Vname AS companyInfoVname")

				.addLeftJoin("TB_CompanyBankInfo BI ON BI.Id = A.CompanyBankInfoId AND 1=1")//公司银行账户管理
				.addField("BI.Vid AS cVid")//账户编码
				.addField("BI.Vyhzhmc AS cVyhzhmc")//付款银行户名
				.addField("BI.Vkhh AS cVkhh")//付款开户行
				.addField("BI.Vyhzh AS cVyhzh")//付款银行账号

				.setBid(bid)
				.queryFirstMap();
		return extraParam;
	}
	//获取子列表数据
	@Override
	@Transactional
	public List<Map<String, Object>> getItemList( String bid) throws Exception{
		List<Map<String, Object>> itemList = new TcwCapitalRegisterSon()
				.addLeftJoin("THR_OperateCompanyBankInfo B ON B.Id = A.OperateCompanyBankInfoId")//运营公司银行账户管理
				.addField("B.Vid AS vid")//账户编码
				.addField("B.Vyhzhmc AS vyhzhmc")//付款银行户名
				.addField("B.Vkhh AS vkhh")//付款开户行
				.addField("B.Vyhzh AS vyhzh")//付款银行账号
				.addField("B.AccountType AS accountType")//账户类型
				.addField("CASE " +
						"WHEN B.AccountType = 0 THEN '对公户' " +
						"WHEN B.AccountType  = 1 THEN '个人户' " +
						" ELSE '' END accountTypeTxt")//账户类型
				.addField("'运营服务→预付款' AS vjylx")//交易类型
				//.addField("A.Id AS vjylx")//交易类型

				.setPbid(bid)
				.queryMap();

		return itemList;
	}





}
